package org.wu.framework.inner.lazy.orm.spring.processor;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.inner.lazy.orm.spring.annotation.LazyRepositoryScan;
import org.wu.framework.inner.lazy.orm.spring.util.ScanClassUtil;
import org.wu.framework.lazy.orm.database.jpa.repository.support.LazyRepositoryFactorySupport;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;

import java.util.*;

public class LazyRepositoryImportBeanDefinitionRegistrar1 implements ImportBeanDefinitionRegistrar {




    /**
     * Register bean definitions as necessary based on the given annotation metadata of
     * the importing {@code @Configuration} class.
     * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
     * registered here, due to lifecycle constraints related to {@code @Configuration}
     * class processing.
     * <p>The default implementation is empty.
     *
     * @param importingClassMetadata annotation metadata of the importing class
     * @param registry               current bean definition registry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AnnotationAttributes mapperScanAttrs = AnnotationAttributes
                .fromMap(importingClassMetadata.getAnnotationAttributes(LazyRepositoryScan.class.getName()));

        List<Class<?>> repositoryClass = new ArrayList<>();
        if (mapperScanAttrs != null) {
            Class<?>[] scanRepositoryClass = mapperScanAttrs.getClassArray("scanClass");
            repositoryClass.addAll(Arrays.asList(scanRepositoryClass));
            String[] scanBasePackages = mapperScanAttrs.getStringArray("scanBasePackages");
            Class<?>[] scanBasePackageClasses = mapperScanAttrs.getClassArray("scanBasePackageClasses");
            // 含有包路径
            if (!ObjectUtils.isEmpty(scanBasePackages)) {
                for (String scanBasePackage : scanBasePackages) {
                    List<Class<?>> classes = ScanClassUtil.scanClass(scanBasePackage, null);
                    repositoryClass.addAll(classes);
                }
            }
            // 包含 包路径的class
            if (!ObjectUtils.isEmpty(scanBasePackageClasses)) {
                for (Class<?> scanBasePackageClass : scanBasePackageClasses) {
                    List<Class<?>> classes = ScanClassUtil.scanClass(scanBasePackageClass.getPackage().getName(), null);
                    repositoryClass.addAll(classes);
                }
            }
        }


        // 包含指定注解 LazyRepository 并且集成 LazyJpaRepository

        for (Class<?> clazz : repositoryClass) {
            // 创建 bean

            // 注入容器
            BeanDefinitionBuilder builder = BeanDefinitionBuilder
                    .genericBeanDefinition(clazz, () -> {
                        return LazyRepositoryFactorySupport.createLazyJpaRepository((LazyLambdaStream) new RuntimeBeanReference(LazyLambdaStream.class).getSource(), clazz);
                    });

            builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            BeanDefinition beanDefinition = builder.getBeanDefinition();
            registry.registerBeanDefinition(clazz.getName(), beanDefinition);
        }


        ImportBeanDefinitionRegistrar.super.registerBeanDefinitions(importingClassMetadata, registry);
    }



}
